/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.rafkind.resrev.web.page;

import com.rafkind.resrev.dao.ResourceDao;
import com.rafkind.resrev.data.Color;
import com.rafkind.resrev.data.Condition;
import com.rafkind.resrev.data.Resource;
import com.rafkind.resrev.web.Authorized;
import com.rafkind.resrev.web.Session;
import com.rafkind.resrev.web.page.component.AddResourceButton;
import com.rafkind.resrev.web.page.component.EditOrDeleteResourcePanel;
import com.rafkind.resrev.web.page.component.TitleMenu;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.wicket.Component;
import org.apache.wicket.behavior.SimpleAttributeModifier;
import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
import org.apache.wicket.extensions.markup.html.repeater.data.table.DefaultDataTable;
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;

/**
 *
 * @author dave
 */
@Authorized
public class ResourcesPage extends WebPage {
  
  @SpringBean
  private ResourceDao resourceDao;
  
  public ResourcesPage() {
    add(new TitleMenu("titleMenu"));
    
    List<IColumn<?>> columns = new ArrayList<IColumn<?>>();
    
    final Stylist forColor = new StylistForResourceColor();
    Stylist forCondition = new StylistForResourceCondition();
    
    columns.add(
        new ColorfulPropertyColumn(
          new Model<String>("Resource"), "name", "name", forColor));
    
    columns.add(
        new ColorfulPropertyColumn(
          new Model<String>("Description"), "description", "description", forColor){

      @Override
      public String getCssClass() {
        return "comment";
      }      
    });
    
    columns.add(
        new ColorfulPropertyColumn(
          new Model<String>("Condition"), "currentCondition", "currentCondition", 
          forCondition));
    
    columns.add(
        new ColorfulPropertyColumn(
          new Model<String>("Display Color"), "color", "color", forColor));
    
    columns.add(
        new AbstractColumn<Resource>(new Model<String>("Authorizor")){
      public void populateItem(
          Item<ICellPopulator<Resource>> cellItem, 
          String componentId, 
          IModel<Resource> model) {
        Label label = null;
        if (model.getObject().getAuthorizor() != null) {
          label =
              new Label(
                componentId, 
                new PropertyModel(model, "authorizor.name"));
        } else {
          label = new Label(componentId, "");          
        }
        
        Resource u = model.getObject();
        
        label.add(new SimpleAttributeModifier(
          "style",
          forColor.getStyleFor(model.getObject())));
        
        cellItem.add(label);
      }
      @Override
      public String getSortProperty() {
        return "authorizor.name";
      }

      @Override
      public boolean isSortable() {
        return true;
      }
    });
    
    if (((Session)getSession()).getCurrentUser().isAdmin()) {
      columns.add(new AbstractColumn<Resource>(new Model<String>("Add New Resource")){

        public void populateItem(Item<ICellPopulator<Resource>> cellItem, 
            String id, 
            IModel<Resource> model) {

          cellItem.add(new EditOrDeleteResourcePanel(id, model));
        }

        @Override
        public Component getHeader(String id) {
          return new AddResourceButton(id, new Model(getPage()));
        }             
      });
    }
    
    add(new DefaultDataTable(
        "table", 
        columns, 
        new ResourceDataProvider(this), 
        10));
  }

  public ResourceDao getResourceDao() {
    return resourceDao;
  }
  
  public static class ResourceDataProvider extends SortableDataProvider<Resource> {

    private ResourcesPage resourcesPage;

    public ResourceDataProvider(ResourcesPage resourcesPage) {
      this.resourcesPage = resourcesPage;
      
      setSort("name", true);
    }    
    
    public Iterator<? extends Resource> iterator(int first, int count) {
      SortParam sp = getSort();      
      return resourcesPage.getResourceDao()
          .getAllResources(first, count, sp.getProperty(), sp.isAscending())
          .iterator();
    }

    public IModel<Resource> model(Resource resource) {
      return new DetachableResourceModel(resourcesPage.getResourceDao(), resource);
    }

    public int size() {
      return resourcesPage.getResourceDao().countAllResources();
    }    
  }
  
  public static class DetachableResourceModel 
      extends LoadableDetachableModel<Resource> {

    private int id;
    private ResourceDao resourceDao;
    
    public DetachableResourceModel(ResourceDao resourceDao, Resource resource) {
      super(resource);
      
      this.resourceDao = resourceDao;
      
      id = resource.getId();
    }

    @Override
    public int hashCode() {
      int hash = 7;
      hash = 53 * hash + this.id;
      return hash;
    }   

    @Override
    public boolean equals(Object obj) {
      if (obj == null) {
        return false;
      }
      if (getClass() != obj.getClass()) {
        return false;
      }
      final DetachableResourceModel other = (DetachableResourceModel) obj;
      if (this.id != other.id) {
        return false;
      }
      return true;
    }        

    @Override
    protected Resource load() {
      return resourceDao.getResource(id);
    }    
  }
  
  /*public static class ColorfulPropertyColumn extends PropertyColumn<Resource> {

    private ColorGetter cg;

    public ColorfulPropertyColumn(IModel<String> arg0, String arg1, String arg2) {
      this(arg0, arg1, arg2, new ColorGetterForColor());
    }
    
    public ColorfulPropertyColumn(IModel<String> arg0, String arg1, String arg2, ColorGetter cg) {
      super(arg0, arg1, arg2);
      
      this.cg = cg;
    }

    @Override
    public void populateItem(Item item, String componentId, IModel model) {
      Resource u = (Resource) model.getObject();
      Label label = new Label(componentId, createLabelModel(model));
      
      label.add(createResourceColorAttribute(u, cg));
      item.add(label);
    }       
  }
  
  private static SimpleAttributeModifier createResourceColorAttribute(Resource r, ColorGetter cg) {
    return new SimpleAttributeModifier(
            "style", 
            "color: " + cg.getColor(r)
            );
  }
  
  private static interface ColorGetter {
    String getColor(Resource r);
  }

  private static class ColorGetterForColor implements ColorGetter {

    public String getColor(Resource r) {
      return (r != null && r.getColor() != null 
              ? 
                r.getColor().getHexColor() 
              : 
                Color.DEFAULT.getHexColor());
    }    
  }
  
  private static class ColorGetterForCondition implements ColorGetter {

    public String getColor(Resource r) {
      return (r != null && r.getCurrentCondition() != null 
              ? 
                r.getCurrentCondition().getHexColor() 
              : 
                Condition.UNKNOWN.getHexColor());
    }    
  }*/
  
  public static class StylistForResourceColor 
      implements Stylist<Resource> {
    public String getStyleFor(Resource r) {
      return (r != null && r.getColor() != null 
              ? 
                r.getColor().getHexColor() 
              : 
                Color.DEFAULT.getHexColor());
    }    
  }
  
  public static class StylistForResourceCondition 
      implements Stylist<Resource> {
    public String getStyleFor(Resource r) {
      return (r != null && r.getCurrentCondition() != null 
              ? 
                r.getCurrentCondition().getHexColor() 
              : 
                Condition.UNKNOWN.getHexColor());
    }    
  }
}